package be.sc.classicnetwork.controller;

import java.util.Enumeration;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.propertyeditors.CustomNumberEditor;
import org.springframework.beans.propertyeditors.StringTrimmerEditor;
import org.springframework.core.task.TaskExecutor;
import org.springframework.validation.BindException;
import org.springframework.web.bind.ServletRequestDataBinder;
import org.springframework.web.multipart.support.ByteArrayMultipartFileEditor;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.SimpleFormController;

import be.sc.classicnetwork.controller.beans.EntityPropertyEditor;
import be.sc.classicnetwork.model.Contact;
import be.sc.classicnetwork.model.Image;
import be.sc.classicnetwork.model.Location;
import be.sc.classicnetwork.model.Make;
import be.sc.classicnetwork.model.Site;
import be.sc.classicnetwork.model.Type;
import be.sc.classicnetwork.service.ServiceLocator;

/**
 * Abstract Form controller.
 */
public class AbstractFormController extends SimpleFormController {

	private ServiceLocator serviceLocator;

	private TaskExecutor taskExecutor;

	/**
	 * @see org.springframework.web.servlet.mvc.AbstractFormController#handleInvalidSubmit(javax.servlet.http.HttpServletRequest,
	 *      javax.servlet.http.HttpServletResponse)
	 */
	@Override
	protected ModelAndView handleInvalidSubmit(HttpServletRequest request,
			HttpServletResponse response) throws Exception {
		BindException errors = getErrorsForNewForm(request);
		errors.reject("duplicateFormSubmission", "Duplicate form submission");
		return showForm(request, response, errors);
	}

	/**
	 * @see org.springframework.web.servlet.mvc.BaseCommandController#initBinder(javax.servlet.http.HttpServletRequest,
	 *      org.springframework.web.bind.ServletRequestDataBinder)
	 */
	@Override
	protected void initBinder(HttpServletRequest request,
			ServletRequestDataBinder binder) throws Exception {
		// bind images
		binder.registerCustomEditor(byte[].class,
				new ByteArrayMultipartFileEditor());

		// bind Numbers
		binder.registerCustomEditor(Integer.class, new CustomNumberEditor(
				Integer.class, true));
		binder.registerCustomEditor(Double.class, new CustomNumberEditor(
				Double.class, true));
		binder.registerCustomEditor(Make.class, new EntityPropertyEditor(
				Make.class));
		binder.registerCustomEditor(Site.class, new EntityPropertyEditor(
				Site.class));
		binder.registerCustomEditor(Type.class, new EntityPropertyEditor(
				Type.class));
		binder.registerCustomEditor(Image.class, new EntityPropertyEditor(
				Image.class));
		binder.registerCustomEditor(Contact.class, new EntityPropertyEditor(
				Contact.class));
		binder.registerCustomEditor(Location.class, new EntityPropertyEditor(
				Location.class));
		binder
				.registerCustomEditor(String.class, new StringTrimmerEditor(
						true));
	}

	/**
	 * getMaxIndex.
	 */
	@SuppressWarnings("unchecked")
	protected int getMaxIndex(HttpServletRequest request, String property) {
		int maxIndex = -1;
		for (Enumeration<String> parameters = request.getParameterNames(); parameters
				.hasMoreElements();) {
			String parameterName = parameters.nextElement();
			if (parameterName.startsWith(property)) {
				int startIndex = parameterName.indexOf("[", property.length());
				int endIndex = parameterName.indexOf("]", property.length());
				if ((startIndex == -1) || (endIndex == -1)) {
					return (-1);
				}
				int index = Integer.parseInt(parameterName.substring(
						(startIndex + 1), endIndex));
				if (index > maxIndex) {
					maxIndex = index;
				}
			}
		}
		return (maxIndex);
	}

	/**
	 * Sets the specified message in the request..
	 */
	protected void showMessage(HttpServletRequest request, String message) {
		request.setAttribute("message", message);
	}

	public TaskExecutor getTaskExecutor() {
		return taskExecutor;
	}

	public void setTaskExecutor(TaskExecutor taskExecutor) {
		this.taskExecutor = taskExecutor;
	}

	public ServiceLocator getServiceLocator() {
		return serviceLocator;
	}

	public void setServiceLocator(ServiceLocator serviceLocator) {
		this.serviceLocator = serviceLocator;
	}

}
